package com.cet.qz.unit01.chapter1_3;

import edu.princeton.cs.algs4.StdRandom;

import java.util.Iterator;

/**
 * @program: algorithm
 * @description: 随机队列
 * @author: 陈恩涛
 * @create: 2021-04-22 09:11
 **/
public class RandomQueue<Item> implements Iterable<Item> {

    private Item[] a = (Item[]) new Object[1];
    private int first, last, n;

    /**
     *方法描述： 判断队列是否为空
     *
     * @return boolean
     * @author chenentao
     * @date 2021/4/22 9:35
     */
    public boolean isEmpty() {
        return n == 0;
    }

    /**
     *方法描述： 将原数组a中first到last-1的元素，拷贝到新数组的0到last-first-1
     *
     * @param max
     * @return void
     * @author chenentao
     * @date 2021/4/22 9:45
     */
    private void resize(int max) {
        Item[] items = (Item[]) new Object[max];
        int j = first;
        for (int i = 0; i < n; i++) {
            items[i] = a[j++];
        }
        a = items;
        first = 0;
        last = n;
    }

    /**
     *方法描述： 添加一个元素
     *
     * @param item
     * @return void
     * @author chenentao
     * @date 2021/4/22 9:35
     */
    public void enqueue(Item item) {
        if (last == a.length) {
            if (n < a.length) {
                resize(a.length);
            } else {
                resize(2 * a.length);
            }
        }
        a[last++] = item;
        n++;
    }

    /**
     *方法描述： 删除并随机返回一个元素
     *
     * @param
     * @return Item
     * @author chenentao
     * @date 2021/4/22 9:35
     */
    public Item dequeue() {
        if (isEmpty()) {
            throw new RuntimeException("RandomQueue is empty!");
        }
        int r = first + StdRandom.uniform(last - first);
        Item temp = a[first];
        a[first] = a[r];
        a[r] = temp;

        Item result = a[first];
        a[first++] = null;
        n--;
        if (n == a.length / 4) {
            resize(a.length /2);
        }
        return result;
    }

    /**
     *方法描述： 随机返回一个元素
     *
     * @param
     * @return Item
     * @author chenentao
     * @date 2021/4/22 9:36
     */
    public Item sample() {
        if (isEmpty()) {
            throw new RuntimeException("RandomQueue is empty!");
        }
        int r = first + StdRandom.uniform(last - first);
        return a[r];
    }

    @Override
    public Iterator<Item> iterator() {
        return new RandomQueueIterator(first,last);
    }

    class RandomQueueIterator implements Iterator<Item> {

        private int head;
        private int tail;

        public RandomQueueIterator(int head, int tail) {
            this.head = head;
            this.tail = tail;

            for (int i = head; i < tail; i++) {
                int r = i + StdRandom.uniform(tail - head - i);
                Item temp = a[i];
                a[i] = a[r];
                a[r] = temp;
            }
        }

        @Override
        public boolean hasNext() {
            return head != tail;
        }

        @Override
        public Item next() {
            return a[head++];
        }

        @Override
        public void remove() {

        }
    }


    public static void main(String[] args) {
        RandomQueue<Card> randomQueue = new RandomQueue<>();
        String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
        String[] colors = {"spade","heart","diamond","clubs"};
        //初始化桥牌
        for (String color : colors) {
            for (String num : nums) {
                randomQueue.enqueue(new Card(num,color));
            }
        }

        for (Card card : randomQueue) {
            System.out.println(card);
        }

        System.out.println("==================");

        //发牌
        for (int i = 1; i <= 4; i++) {
            System.out.println("玩家"+i+"手牌如下：");
            for (int j = 0; j < 13; j++) {
                System.out.println(randomQueue.dequeue());
            }
        }

     }
}

class Card {
    private String num;
    private String color;

    public Card(String num, String color) {
        this.num = num;
        this.color = color;
    }

    public Card() {
    }

    @Override
    public String toString() {
        return "Card{" +
                "num='" + num + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}
